package yiran.onemonthcard.system;

import org.bukkit.Bukkit;
import org.bukkit.Particle;
import org.bukkit.Sound;
import org.bukkit.entity.Player;
import yiran.onemonthcard.OneMonthCard;
import yiran.onemonthcard.data.DatabaseManager;
import yiran.onemonthcard.lang.LangHelper;

import java.time.LocalDate;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class OneMonthCardSystem {
    private final OneMonthCard plugin;
    private final Map<String, OneMonthCardData> playerDataMap;
    public final DatabaseManager databaseManager;

    public OneMonthCardSystem(OneMonthCard plugin) {
        this.plugin = plugin;
        this.playerDataMap = new HashMap<>();
        this.databaseManager = new DatabaseManager(plugin);
    }
    
    // 月卡数据内部类
    public static class OneMonthCardData {
        private final String playerName; // 改为使用玩家名称
        private LocalDate purchaseDate;
        private LocalDate lastClaimDate;
        private int remainingDays;
        private boolean isActive;
        
        public OneMonthCardData(String playerName) {
            this.playerName = playerName;
        }

        public String getPlayerId() { return playerName; }
        public LocalDate getPurchaseDate() { return purchaseDate; }
        public void setPurchaseDate(LocalDate purchaseDate) { this.purchaseDate = purchaseDate; }
        public LocalDate getLastClaimDate() { return lastClaimDate; }
        public void setLastClaimDate(LocalDate lastClaimDate) { this.lastClaimDate = lastClaimDate; }
        public int getRemainingDays() { return remainingDays; }
        public void setRemainingDays(int remainingDays) { this.remainingDays = remainingDays; }
        public boolean isActive() { return isActive; }
        public void setActive(boolean active) { isActive = active; }
    }

    public void closeDatabase() {
        databaseManager.closeConnection();
    }

    public void purchaseOneMonthCard(Player player) {
        String playerName = player.getName();
        OneMonthCardData data = playerDataMap.get(playerName);

        if (data == null) {
            data = new OneMonthCardData(playerName);
            data.setPurchaseDate(LocalDate.now());
            data.setRemainingDays(plugin.getConfig().getInt("duration", 30));
            data.setActive(true);
            player.sendMessage(LangHelper.getString("purchase_success",
                    plugin.getConfig().getInt("duration", 30)
            ));
        } else {
            int duration = plugin.getConfig().getInt("duration", 30);
            data.setRemainingDays(data.getRemainingDays() + duration);
            data.setPurchaseDate(LocalDate.now());
            data.setActive(true);
            player.sendMessage(LangHelper.getString("messages.renew_success", duration));
        }

        if (shouldClaimReward(data)) {
            giveReward(player, data);
        }

        playerDataMap.put(playerName, data);
        databaseManager.saveOneMonthCardData(data);
    }

    public void giveDailyReward(Player player) {
        String playerId = player.getName();
        OneMonthCardData data = playerDataMap.get(playerId);
        if (data == null || !data.isActive()) {
            player.sendMessage(LangHelper.getString("errors.no_OneMonthCard"));
            return;
        }

        if (shouldClaimReward(data)) {
            giveReward(player, data);
        } else {
            player.sendMessage(LangHelper.getString("errors.already_claimed"));
        }
    }

    private boolean shouldClaimReward(OneMonthCardData data) {
        if (data.getLastClaimDate() == null) return true;
        return !data.getLastClaimDate().isEqual(LocalDate.now());
    }

    public void checkExpiredCards() {
        // 处理数据库中的过期玩家（包括离线玩家）
        List<OneMonthCardData> expiredData = databaseManager.loadAllExpiredCards();
        for (OneMonthCardData data : expiredData) {
            // 避免重复处理已在内存中的玩家
            if (!playerDataMap.containsKey(data.getPlayerId())) {
                handleCardExpiration(data.getPlayerId(), data);
            }
        }

        // 处理内存中的在线玩家
        for (Map.Entry<String, OneMonthCardData> entry : playerDataMap.entrySet()) {
            OneMonthCardData data = entry.getValue();
            if (data.getRemainingDays() <= 0 && data.isActive()) {
                handleCardExpiration(entry.getKey(), data);
            }
        }
    }

    public void handleCardExpiration(String playerName, OneMonthCardData data) {
        data.setActive(false);
        databaseManager.saveOneMonthCardData(data);

        if (playerDataMap.containsKey(playerName)) {
            playerDataMap.get(playerName).setActive(false);
        }

        Player player = Bukkit.getPlayer(playerName);
        if (player != null) {
            // 显示到期标题
            if (plugin.getConfig().getBoolean("effects.titles", true)) {
                player.sendTitle(
                        LangHelper.getString("messages.expired_title"),
                        LangHelper.getString("messages.expired_subtitle"),
                        10, 70, 20
                );
            }

            executeExpiredCommands(player);
        }
        plugin.getLogger().info("玩家 " + playerName + " 的月卡已到期");
    }

    private void executeExpiredCommands(Player player) {
        try {
            List<String> expiredCommands = plugin.getConfig().getStringList("expired-commands");
            for (String command : expiredCommands) {
                String processedCommand = command
                        .replace("%player%", player.getName())
                        .replace("%uuid%", player.getUniqueId().toString());

                if (plugin.getConfig().getBoolean("log-expired-commands", false)) {
                    plugin.getLogger().info("执行到期指令: " + processedCommand);
                }

                Bukkit.getScheduler().runTask(plugin, () -> {
                    if (plugin.isEnabled()) {
                        Bukkit.dispatchCommand(Bukkit.getConsoleSender(), processedCommand);
                    }
                });
            }
        } catch (Exception e) {
            plugin.getLogger().severe("执行到期指令时出错: " + e.getMessage());
        }
    }

    // 数据管理方法
    public void loadPlayerData() {
        for (Player player : Bukkit.getOnlinePlayers()) {
            OneMonthCardData data = databaseManager.loadOneMonthCardData(player.getName());
            if (data != null) {
                playerDataMap.put(player.getName(), data);
                // 新增：加载时检查是否过期
                if (data.isActive() && data.getRemainingDays() <= 0) {
                    handleCardExpiration(player.getName(), data);
                }
            }
        }
    }

    public void savePlayerData() {
        // 保存所有玩家数据
        for (OneMonthCardData data : playerDataMap.values()) {
            databaseManager.saveOneMonthCardData(data);
        }
    }

    public void handlePlayerQuit(Player player) {
        String playerName = player.getName();
        OneMonthCardData data = playerDataMap.get(playerName);
        if (data != null) {
            databaseManager.saveOneMonthCardData(data);
        }
    }

    public Map<String, OneMonthCardData> getPlayerDataMap() {
        return playerDataMap;
    }

    public void checkAndGiveAutoReward(Player player) {
        if (!plugin.getConfig().getBoolean("auto-claim", true)) {
            return;
        }

        String playerName = player.getName();
        OneMonthCardData data = playerDataMap.get(playerName);
        if (data == null || !data.isActive()) {
            return;
        }

        if (shouldClaimReward(data)) {
            giveReward(player, data);
        }
    }

    private void giveReward(Player player, OneMonthCardData data) {

        goodGetRewardDemo(player);
        plugin.getConfig().getStringList("daily-rewards").forEach(reward -> {
            Bukkit.dispatchCommand(Bukkit.getConsoleSender(), reward.replace("%player%", player.getName()));
        });

        // 更新最后领取日期为今天
        data.setLastClaimDate(LocalDate.now());
        databaseManager.saveOneMonthCardData(data);
    }

    private void goodGetRewardDemo(Player player) {
        if (!player.isOnline()) return;

        try {
            if (plugin.getConfig().getBoolean("effects.titles", true)) {
                player.sendTitle(
                        plugin.getMessage("messages.reward_title"),
                        plugin.getMessage("messages.reward_subtitle"),
                        10, 70, 20
                );
            }

            if (plugin.getConfig().getBoolean("effects.sounds", true)) {
                player.playSound(player.getLocation(), Sound.ENTITY_PLAYER_LEVELUP, 1.0f, 1.0f);
            }

            if (plugin.getConfig().getBoolean("effects.particles", true)) {
                player.getWorld().spawnParticle(Particle.FIREWORKS_SPARK,
                        player.getLocation().add(0, 2, 0),
                        50, 1, 1, 1, 0.5);
                player.getWorld().spawnParticle(Particle.HEART,
                        player.getLocation().add(0, 2, 0),
                        10, 1, 1, 1, 0.1);
            }
        } catch (Exception e) {
            plugin.getLogger().warning("生成特效时出错: " + e.getMessage());
        }
    }


    public void loadAllPlayerData() {
        // 加载所有玩家数据（不只是在线玩家）
        List<OneMonthCardData> allData = databaseManager.loadAllOneMonthCardData();
        for (OneMonthCardData data : allData) {
            playerDataMap.put(data.getPlayerId(), data);
            // 检查是否过期
            if (data.isActive() && data.getRemainingDays() <= 0) {
                handleCardExpiration(data.getPlayerId(), data);
            }
        }
        plugin.getLogger().info("已加载所有玩家月卡数据");
    }


}
